home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / ira_src / irapost.c < prev    next >
C/C++ Source or Header  |  1999-02-03  |  12KB  |  444 lines

  1. ;/*
  2.    failat 20
  3.     if not exists all.sym
  4.       sc makegst=all.sym p:all.c
  5.    endif
  6.    sc gst=all.sym parms=register nostackcheck optime IRApost.c
  7.    slink lib:c.o IRApost.o to IRApost sc sd nd lib lib:sc.lib
  8.     QUIT
  9. */
  10. /*************************************************/
  11. /*    PostProcessor for IRA v1.xx,                  */
  12. /*    Original coded by Comedian/Hoaxers.  (08/93)  */
  13. /* Enhanced by SiliconSurfer/Phantasm.  (12/94)  */
  14. /*                                               */
  15. /*    Latest updates: 08.12.94                      */
  16. /*************************************************/
  17.  
  18.  
  19. #define VERSION     "1"
  20. #define REVISION   "06"
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <stdarg.h>
  27. #include <ctype.h>
  28. #include <exec/memory.h>
  29. #include <clib/exec_protos.h>
  30. #include <pragmas/exec_pragmas.h>
  31. #include <libraries/dosextens.h>
  32.  
  33. /* #include "exec_calls.h" */
  34.  
  35.  
  36. UBYTE version[]="$VER: IRAPost V"VERSION"."REVISION" ("__DATE__")  (c)1993,94 Tim Ruehsen\n\n";
  37.  
  38.  
  39. #define BUFFERLENGTH  1024
  40. #define GETLINE       fgets(buffer,BUFFERLENGTH,sourcefile)
  41. #define PUTLINE       fputs(buffer,destfile)
  42. #define GETLINEFD     fgets(buffer,BUFFERLENGTH,FDfile)
  43.  
  44.  
  45. char   buffer[BUFFERLENGTH];
  46. char   sourcename[80], destname[80], incname[80], FDname[80], libname[80];
  47. FILE  *sourcefile, *destfile, *incfile, *FDfile;
  48. char  *buffpeek;
  49. int    swapcount, diffcount;
  50. char **LibCallNames;
  51. int   *LibCallFlags;
  52. int   *LibCallOffs;
  53. int    LIB_CALLS;
  54. char   BaseName[80];
  55. int    firstbias, bias;
  56.  
  57.  
  58. int    ARGC;
  59. char **ARGV;
  60.  
  61.  
  62. extern int
  63.     onbreak(void (*)());
  64.  
  65.  
  66. void Explain(char *);
  67. void InitPrg(void);
  68. void ExitPrg(char *, ...);
  69. void ReadFD(void);
  70. void TestSource(void);
  71. void ProcessSource(void);
  72. void ExtractLibBase(void);
  73. void SymbolizeLibCalls(void);
  74. void InsertSymbolicLib(char *);
  75. void chkabort(void);
  76. void _abort(void);
  77. /*****************************************************************************/
  78. void _abort(void)
  79. {
  80.     fflush(stdout);
  81.     ExitPrg("***User-Break\n");
  82. }
  83.  
  84. /*****************************************************************************/
  85. void main(int argc, char *argv[])
  86. {
  87.     ARGC = argc;
  88.     ARGV = argv;
  89.  
  90.     InitPrg();
  91.     ReadFD();
  92.     TestSource();
  93.     ProcessSource();
  94.     ExitPrg(0);
  95. }
  96.  
  97.  
  98. /*****************************************************************************/
  99. void ProcessSource(void)
  100. {
  101.     printf("Analyzing and processing sourcecode...");
  102.     ExtractLibBase();
  103.     SymbolizeLibCalls();
  104.     fclose(sourcefile);sourcefile=0;
  105.     fclose(destfile);destfile=0;
  106.     if (ARGC == 3) {
  107.         remove(sourcename);
  108.         rename(destname,sourcename);
  109.     }
  110.     printf("Done.\n");
  111.  
  112.     strlwr(libname);
  113.     if (swapcount == 1)
  114.         printf("Replaced %d %s.library offset with its symbolic name.\n",swapcount,libname);
  115.     else
  116.         printf("Replaced %d %s.library offsets with their symbolic names.\n",swapcount,libname);
  117.     if (swapcount > 1) {
  118.         if (diffcount == 1)
  119.             printf("No different %s.library calls are used in the sourcecode.\n",libname);
  120.         else
  121.             printf("%d different %s.library calls are used in the sourcecode.\n",diffcount,libname);
  122.     }
  123.     printf("\n");
  124. }
  125. /*****************************************************************************/
  126. void SymbolizeLibCalls(void)
  127. {
  128.     char ts1[80], ts2[80], ts3[80], ts4[80];
  129.     char ts5[80], ts6[80], ts7[80], ts8[80], ts9[80], ts10[80];
  130.     int  ts1len, ts2len, ts3len, ts4len;
  131.     int  ts5len, ts6len, ts7len, ts8len, ts9len, ts10len;
  132.     int  flag = 0;
  133.  
  134.  
  135.     if (!stricmp("EXEC",libname))
  136.     {
  137.         strcpy(ts5, "\tMOVEA.L\tABSEXECBASE,A6");
  138.         strcpy(ts6, "\tMOVE.L\t(ABSEXECBASE).W,A6");
  139.         strcpy(ts7, "\tMOVE.L\tABSEXECBASE,A6");
  140.         strcpy(ts8, "\tMOVEA.L\t(ABSEXECBASE).W,A6");
  141.         strcpy(ts9, "\tMOVE.L\tABSEXECBASE.W,A6");
  142.         strcpy(ts10,"\tMOVEA.L\tABSEXECBASE.W,A6");
  143.     }
  144.     else
  145.     {
  146.         strcpy(ts5, "\tEND");
  147.         strcpy(ts6, "\tEND");
  148.         strcpy(ts7, "\tEND");
  149.         strcpy(ts8, "\tEND");
  150.         strcpy(ts9, "\tEND");
  151.         strcpy(ts10,"\tEND");
  152.     }
  153.     strcpy(ts1,"\tMOVEA.L\t");
  154.     strcat(ts1,BaseName);
  155.     strcpy(ts2,ts1);
  156.     strcat(ts1,"(PC),A6");
  157.     strcat(ts2,",A6");
  158.     strcpy(ts3,"\tMOVE.L\t");
  159.     strcat(ts3,BaseName);
  160.     strcpy(ts4,ts3);
  161.     strcat(ts3,"(PC),A6");
  162.     strcat(ts4,",A6");
  163.  
  164.     ts1len = strlen(ts1);
  165.     ts2len = strlen(ts2);
  166.     ts3len = strlen(ts3);
  167.     ts4len = strlen(ts4);
  168.     ts5len = strlen(ts5);
  169.     ts6len = strlen(ts6);
  170.     ts7len = strlen(ts7);
  171.     ts8len = strlen(ts8);
  172.     ts9len = strlen(ts9);
  173.     ts10len= strlen(ts10);
  174.  
  175. /*
  176.     printf("\n%s\n",ts1);
  177.     printf("%s\n",ts2);
  178.     printf("%s\n",ts3);
  179.     printf("%s\n",ts4);
  180.     printf("%s\n",ts5);
  181.     printf("%s\n",ts6);
  182.     printf("%s\n",ts7);
  183.     printf("%s\n",ts8);
  184. */
  185.  
  186.  
  187.     swapcount = 0;
  188.     diffcount = 0;
  189.  
  190.     while (stricmp(buffer,"\tEND\n"))
  191.     {
  192.         chkabort();
  193.  
  194.         /* Find line where A6 is loaded with base of library */
  195.         do {
  196.             GETLINE;
  197.             PUTLINE;
  198.         } while(strnicmp(buffer,ts1,ts1len) &&
  199.                 strnicmp(buffer,ts2,ts2len) &&
  200.                 strnicmp(buffer,ts3,ts3len) &&
  201.                 strnicmp(buffer,ts4,ts4len) &&
  202.                 strnicmp(buffer,ts5,ts5len) &&
  203.                 strnicmp(buffer,ts6,ts6len) &&
  204.                 strnicmp(buffer,ts7,ts7len) &&
  205.                 strnicmp(buffer,ts8,ts8len) &&
  206.                 strnicmp(buffer,ts9,ts9len) &&
  207.                 strnicmp(buffer,ts10,ts10len) &&
  208.                 stricmp(buffer,"\tEND\n"));
  209.  
  210. /*        printf("-->%s\n",buffer); */
  211.  
  212.         flag = 0;
  213.         while ((stricmp(buffer,"\tEND\n") != 0) && (flag == 0))
  214.         {
  215.             chkabort();
  216.             GETLINE;
  217.             if(!strnicmp(buffer,"\tRTS",4))      flag = 1;
  218.             else if(!strnicmp(buffer,"\tBRA",4)) flag = 1;
  219.             else if(!strnicmp(buffer,"\tBSR",4)) flag = 1;
  220.             else if(!strnicmp(buffer,"\tEXG\tA6",7)) flag = 1;
  221.             else if((buffpeek = strstr(buffer,",A6")) ||
  222.                     (buffpeek = strstr(buffer,",a6")))
  223.             {
  224.                 flag = 1;
  225.                 if(!strnicmp(buffer,ts1,ts1len)) flag = 0;
  226.                 if(!strnicmp(buffer,ts2,ts2len)) flag = 0;
  227.                 if(!strnicmp(buffer,ts3,ts3len)) flag = 0;
  228.                 if(!strnicmp(buffer,ts4,ts4len)) flag = 0;
  229.                 if(!strnicmp(buffer,ts5,ts5len)) flag = 0;
  230.                 if(!strnicmp(buffer,ts6,ts6len)) flag = 0;
  231.                 if(!strnicmp(buffer,ts7,ts7len)) flag = 0;
  232.                 if(!strnicmp(buffer,ts8,ts8len)) flag = 0;
  233.                 if(!strnicmp(buffer,ts9,ts9len)) flag = 0;
  234.                 if(!strnicmp(buffer,ts10,ts10len)) flag = 0;
  235.             } else {
  236.                 if((!strnicmp(buffer,"\tJSR\t-",6)) && (buffpeek = strstr(buffer,"(A6)")))
  237.                 {
  238.                     InsertSymbolicLib("JSR");
  239.                 }
  240.                 else if((!strnicmp(buffer,"\tJMP\t-",6)) && (buffpeek = strstr(buffer,"(A6)")))
  241.                 {
  242.                     InsertSymbolicLib("JMP");
  243.                 }
  244.                 else if(!strnicmp(buffer,"\tJSR",4)) flag = 1;
  245.                 else if(!strnicmp(buffer,"\tJMP",4)) flag = 1;
  246.             }
  247.             PUTLINE;
  248.         }
  249.  
  250.     }
  251. }
  252. /*****************************************************************************/
  253. void InsertSymbolicLib(char *mnemonic)
  254. {
  255.     long call, i=0;
  256.  
  257.     if (buffer[6]=='$') stch_l(&buffer[7],&call);
  258.     else call = atoi(&buffer[6]);
  259.  
  260.     if ((call >= firstbias) && (call%6 == 0))
  261.     {
  262.         while((i<LIB_CALLS) && (call != LibCallOffs[i])) i++;
  263.         if (i < LIB_CALLS)
  264.         {
  265.             sprintf(buffer,"\t%s\t_LVO%s(A6)\n", mnemonic, LibCallNames[i]);
  266.             swapcount++;
  267.  
  268.             if (LibCallFlags[i] == 0)
  269.             {
  270.                 fprintf(incfile,"_LVO%s\tEQU\t-%d\n", LibCallNames[i], call);
  271.                 LibCallFlags[i] = 1;
  272.                 diffcount++;
  273.             }
  274.         }
  275.     }
  276. }
  277. /*****************************************************************************/
  278. void ExtractLibBase(void)
  279. {
  280. char ID[] = "; IRA PostProcessor v"VERSION"."REVISION" ("__DATE__")  (c)1993,94 Tim Ruehsen\n\n";
  281.  
  282.     GETLINE;
  283.     if (!strncmp(buffer, ID, 10)) GETLINE;
  284.     fputs(ID, destfile);
  285.     fprintf(destfile, "\tinclude\t\"%s\"\n", incname);
  286.  
  287.     do {
  288.         chkabort();
  289.         GETLINE;
  290.         PUTLINE;
  291.     } while(strnicmp(buffer,"\tSECTION",8) && stricmp(buffer,"\tEND\n"));
  292. }
  293. /*****************************************************************************/
  294. void ReadFD(void)
  295. {
  296. int publics, functions, publicflag, len, i;
  297.  
  298.     printf("Analysing FD file (%s) ...",FDname);
  299.  
  300.     if (!(FDfile = fopen(FDname, "r")))
  301.         ExitPrg("Couldn't open %s",FDname);
  302.  
  303.     /* if there is no ##base entry in the FD file */
  304.     strcpy(BaseName,libname);
  305.     strcat(BaseName,"BASE");
  306.  
  307.     publicflag = 1;
  308.     do {
  309.         chkabort();
  310.         GETLINEFD;
  311.         if (isalpha(buffer[0]) && publicflag) LIB_CALLS++;
  312.         else if (!strncmp(buffer,"##public",8)) publicflag = 1;
  313.         else if (!strncmp(buffer,"##privat",8)) publicflag = 0;
  314.     } while (stricmp(buffer,"##end\n"));
  315.     fclose(FDfile);
  316.  
  317.  
  318.     if (!(FDfile = fopen(FDname, "r")))
  319.         ExitPrg("Couldn't open %s",FDname);
  320.     if (!(LibCallNames=(char **)AllocMem(LIB_CALLS*sizeof(char *), MEMF_CLEAR)))
  321.         ExitPrg("AllocMem(%ul, %x) failed.", LIB_CALLS*sizeof(char *), MEMF_CLEAR);
  322.     if (!(LibCallFlags=(int *)AllocMem(LIB_CALLS*sizeof(int), MEMF_CLEAR)))
  323.         ExitPrg("AllocMem(%ul, %x) failed.", LIB_CALLS*sizeof(int), MEMF_CLEAR);
  324.     if (!(LibCallOffs=(int *)AllocMem(LIB_CALLS*sizeof(int), MEMF_CLEAR)))
  325.         ExitPrg("AllocMem(%ul, %x) failed.", LIB_CALLS*sizeof(int), MEMF_CLEAR);
  326.  
  327.  
  328.     publicflag =  1;
  329.     publics    =  0;
  330.     functions  =  0;
  331.     bias       = -1;
  332.     do {
  333.         chkabort();
  334.         GETLINEFD;
  335.         if (isalpha(buffer[0]))
  336.         {
  337.             if (publicflag)
  338.             {
  339.                 len = strchr(buffer,'(') - buffer;
  340.                 if (!(LibCallNames[publics]=(char *)AllocMem(len+1, MEMF_CLEAR)))
  341.                     ExitPrg("AllocMem(%ul, %x) failed.", len+1, MEMF_CLEAR);
  342.                 strncpy(LibCallNames[publics], buffer, len);
  343.                 LibCallNames[publics][len] = 0;
  344.                 LibCallOffs[publics]  = bias+6*functions;
  345. /*                printf("-%d %s\n", LibCallOffs[publics], LibCallNames[publics]); */
  346.                 publics++;
  347.             }
  348.             functions++;
  349.         }
  350.         else if (!strncmp(buffer,"##public",8)) publicflag = 1;
  351.         else if (!strncmp(buffer,"##privat",8)) publicflag = 0;
  352.         else if (!strncmp(buffer,"##base",6))
  353.         {
  354.             for(i=8;isprint(buffer[i]);i++) BaseName[i-8] = buffer[i];
  355.             BaseName[i-8]=0;
  356.             strupr(BaseName);
  357.         }
  358.         else if (!strncmp(buffer,"##bias",6))
  359.         {
  360.             if (bias == -1) firstbias = atoi(&buffer[7]);
  361.             bias = atoi(&buffer[7]);
  362.             functions = 0;
  363.         }
  364.     } while (stricmp(buffer,"##end\n"));
  365.     fclose(FDfile);
  366.     FDfile = 0;
  367.  
  368.     printf("%s ...",BaseName);
  369.     printf("Done.\n");
  370. }
  371. /*****************************************************************************/
  372. void TestSource(void)
  373. {
  374.     GETLINE;
  375.  
  376.     if (strnicmp(buffer,"; IRA V1",8))
  377.         ExitPrg("The specified sourcefile is not generated by IRA v1.xx");
  378.  
  379.     PUTLINE;
  380. }
  381. /*****************************************************************************/
  382. void InitPrg(void)
  383. {
  384.     if (onbreak(_abort)) exit(0);
  385.  
  386.     if (ARGC == 4 || ARGC == 3)
  387.     {
  388.         strcpy(libname, ARGV[1]);
  389.         strupr(libname);             /* Convert to upper case */
  390.         sprintf(FDname, "FD:%s_lib.fd", ARGV[1]);
  391.         strcpy(sourcename, ARGV[2]);
  392.         if (ARGC == 4) strcpy(destname, ARGV[3]);
  393.         else           strcpy(destname, "IRAdummy.s");
  394.         sprintf(incname, "IRA_%s.i", libname);
  395.     }
  396.     else Explain(ARGV[0]);
  397.  
  398.     if (!(sourcefile = fopen(sourcename, "r")))
  399.         ExitPrg("Couldn't open %s", sourcename);
  400.  
  401.     if (!(destfile = fopen(destname, "w")))
  402.         ExitPrg("Couldn't write to %s", destfile);
  403.  
  404.     if (!(incfile = fopen(incname, "w")))
  405.         ExitPrg("Couldn't write to %s", incname);
  406. }
  407. /*****************************************************************************/
  408. void ExitPrg(char *errtext, ...)
  409. {
  410. va_list arguments;
  411. int i;
  412.  
  413.     if (errtext) {
  414.         va_start(arguments,errtext);
  415.         vprintf(errtext,arguments);
  416.         printf("\n");
  417.         va_end(arguments);
  418.     }
  419.  
  420.     if (sourcefile) fclose(sourcefile);
  421.     if (destfile)   fclose(destfile);
  422.     if (incfile)    fclose(incfile);
  423.  
  424.     if (LibCallNames) {
  425.         for(i=0;i<LIB_CALLS;i++) FreeMem(LibCallNames[i], strlen(LibCallNames[i]) + 1);
  426.         FreeMem(LibCallNames, LIB_CALLS*sizeof(char **));
  427.     }
  428.     if (LibCallOffs)  FreeMem(LibCallOffs,  LIB_CALLS*sizeof(int));
  429.     if (LibCallFlags) FreeMem(LibCallFlags, LIB_CALLS*sizeof(int));
  430.  
  431.     exit(0);
  432. }
  433. /*****************************************************************************/
  434. void Explain(char *exename)
  435. {
  436.     printf("\nIRA PostProcessor v"VERSION"."REVISION" by Tim Ruehsen. Idea by Morten Eriksen.\n\n");
  437.     printf("Usage: %s libname sourcefile [destfile]\n\n",exename);
  438.     printf("'libname'    name of library who's calls are searched for.\n");
  439.     printf("'sourcefile' must be an assembly sourcefile produced by IRA v1.xx.\n");
  440.     printf("'destfile'   is where you want to save the new, processed assembly sourcefile.\n\n");
  441.     ExitPrg(0);
  442. }
  443. /*****************************************************************************/
  444.